#include "projectinfoimport.h"
#include "typeimport.h"

ProjectInfoImport::ProjectInfoImport(QObject *parent) : QObject(parent)
{

}

void ProjectInfoImport::packageParse(QString filePath,Package &parentPackage,QDomElement root)//解析Package信息，获取该工程的package和操作符的树状结构。filePath为SCADE工程的绝对路径，parentPackage为该package信息所在的package，root为Package信息节点
{

    //该节点为Package节点时
    if(root.tagName()=="Package")
    {
        Package a;

        if(root.attributes().contains("href"))//package中的package有独立文件时
        {
            a.isSeparate=true;
            a.packageName=root.attribute("name");
            a.packageFileName=root.attribute("href");
            a.path=parentPackage.path+a.packageName+"_";

            QFile file(filePath+"/"+a.packageFileName);
            if(!file.open(QFile::ReadOnly))
                return;

            //读取该package的独立文件
            QDomDocument doc;

            if(!doc.setContent(&file))
            {
                file.close();
                return;
            }
            file.close();

            QDomElement element=doc.documentElement();
            a.packageNode=element;
            QDomNodeList infoList=element.firstChild().childNodes();

            for(int i=0;i<infoList.count();i++)
            {
                QDomNode node=infoList.at(i);
                QDomElement ele=node.toElement();
                packageParse(filePath,a,ele);

            }

        }
        else {
            a.isSeparate=false;
            a.packageNode=root;

            a.packageName=root.attribute("name");
            a.packageFileName=parentPackage.packageFileName;
            a.path=parentPackage.path+a.packageName+"_";

            QDomNodeList nodeList=root.firstChild().childNodes();
            for(int i=0;i<nodeList.count();i++)
            {
                packageParse(filePath,a,nodeList.at(i).toElement());//递归解析Package节点
            }

        }

        parentPackage.childPackages<<a;
        sProInfo.packages<<a;
    }

    //该节点为Operator节点时
    if(root.tagName()=="Operator")
    {
        Operator a;

        a.operatorName=root.attribute("name");
        a.path=parentPackage.path+a.operatorName;

        if(root.attributes().contains("href"))//package中的operator有独立文件时
        {
            a.isSeparate=true;
            a.operatorFileName=root.attribute("href");

            QFile file(filePath+"/"+a.operatorFileName);
            if(!file.open(QFile::ReadOnly))
                return;

            //读取该操作符的独立文件
            QDomDocument doc;

            if(!doc.setContent(&file))
            {
                file.close();
                return;
            }
            file.close();

            QDomElement element=doc.documentElement();

            a.operatorNode=element;

        }
        else {
            a.isSeparate=false;
            a.operatorNode=root;
            a.operatorFileName=parentPackage.packageFileName;
        }

        parentPackage.operators<<a;
        sProInfo.opeartors<<a;

    }

}

void ProjectInfoImport::proInfoParse(QString defaultfile,QString scadeProjectFilePath,P_SCADEProInfo projectInfo)//解析SCADE工程的工程信息，SCADEProjectFilePath为SCADE工程文件文件路径
{
    //加载SCADE工程文件
    QFile SCADEProFile(scadeProjectFilePath);
    if(!SCADEProFile.open(QFile::ReadOnly))
        return;

    QDomDocument doc;

    if(!doc.setContent(&SCADEProFile))
    {
        SCADEProFile.close();
        return;
    }
    SCADEProFile.close();

    QDomElement root=doc.documentElement();//SCADE工程文件根节点

    QDomNode propsNode=root.namedItem("props");

    QDomNodeList propList=propsNode.childNodes();

    //获取SCADE语言版本
    for(int i=0;i<propList.size();i++)
    {
        QDomElement element=propList.at(i).toElement();
        if(element.attribute("name")=="@SCADE:SAVEVERSION")
        {
            projectInfo->version=element.firstChild().toElement().text();
        }
    }

    QDomNode rootsNode=root.namedItem("roots");
    QDomNodeList folderList=rootsNode.childNodes();

    //获取默认模型文件信息
    QString defaultFile;
    for(int i=0;i<propList.count();i++)
    {
        QDomNode node=propList.at(i);
        QDomElement ele=node.toElement();
        if(ele.attribute("name")=="@SCADE:DEFAULTFILE")
        {
            defaultFile=ele.firstChild().toElement().text();//获取默认模型文件名字
        }

    }

    QList<QString> otherModelFiles;

    for(int i=0;i<folderList.size();i++)
    {
        QDomElement item=folderList.at(i).toElement();
        if(item.tagName()=="FileRef"&&item.attribute("persistAs").endsWith(".xscade"))
        {
            otherModelFiles<<item.attribute("persistAs");

        }
    }

    for(int i=0;i<folderList.size();i++)
    {
        QDomElement element=folderList.at(i).toElement();        

        //获取算法库列表
        if(element.attribute("name")=="SCADE Libraries")
        {
            QDomNodeList libList=element.firstChild().childNodes();//算法库节点列表

            for(int i=0;i<libList.count();i++)
            {
                QDomNode node=libList.at(i);
                QDomElement ele=node.toElement();
                QString libPath=ele.attribute("persistAs");

                projectInfo->libraries<<libPath;

            }

        }

        //模型文件
        if(element.attribute("name")=="Model Files")
        {
            QDomNodeList modelFileList=element.firstChild().childNodes();

            //判断SCADE默认模型文件是否存在
            for(int i=0;i<modelFileList.count();i++)
            {
                QDomNode node=modelFileList.at(i);
                QDomElement ele=node.toElement();

                QString path = QFileInfo(scadeProjectFilePath).absolutePath()+"/"+defaultFile.replace("\\","/");

                QFile file1(path);
                if(!file1.open(QFile::ReadOnly))
                    continue;

                QDomDocument mdoc;
                if(!mdoc.setContent(&file1))
                {
                    file1.close();
                    continue;
                }
                file1.close();
                QDomElement root1=mdoc.documentElement();
                TypeImport typeImporter;
                typeImporter.getTypeList_64(root1);
                projectInfo->logList.append(typeImporter.logList);
//                projectInfo->typeList.append(typeImporter.typeList);

                if(ele.tagName()=="FileRef"&&ele.attribute("persistAs")==defaultFile)//判断默认模型文件是否存在
                {
                    projectInfo->defaultFile= path;
                }
            }

            //获取工程中所有package和顶层操作符的信息
            //QList<QString> otherModelFiles;
            for(int i=0;i<modelFileList.count();i++)
            {
                QDomNode node=modelFileList.at(i);
                QDomElement ele=node.toElement();

                if(ele.tagName()=="Folder"&&ele.attribute("name")=="Separate Files")
                {
                    QDomNodeList nodeList=ele.firstChild().childNodes();

                    for(int i=0;i<nodeList.size();i++)
                    {
                        QDomNode node=nodeList.at(i);

                        QFile file(QFileInfo(SCADEProFile).absolutePath()+"/"+node.toElement().attribute("persistAs"));

                        if(!file.open(QFile::ReadOnly))
                            return;

                        QDomDocument doc;

                        if(!doc.setContent(&file))
                        {
                            file.close();
                            return;
                        }

                        file.close();

                        QDomElement root=doc.documentElement();

                        if(root.toElement().tagName()=="File"&&root.firstChild().firstChild().toElement().tagName()=="Package")
                            otherModelFiles<<node.toElement().attribute("persistAs");
                    }
                }

                if(ele.tagName()=="FileRef"&&ele.attribute("persistAs").endsWith(".xscade"))
                    otherModelFiles<<ele.attribute("persistAs");
            }




        }


        //子项目
        if(element.tagName()=="FileRef"&&element.attribute("persistAs").endsWith(".etp"))
        {
            QString etpFileDir=QFileInfo(scadeProjectFilePath).absolutePath();
            QString libFilePath=element.attribute("persistAs").replace("\\","/");
            QString libFileFullPath=etpFileDir+"/"+libFilePath;
            if(QFileInfo(element.attribute("persistAs")).fileName()!=QFileInfo(scadeProjectFilePath).fileName())
            {
                projectInfo->projectLibsName.append(libFileFullPath);
            }


        }

        if(element.tagName()=="Folder")
        {
            QDomNodeList nodeList=element.firstChild().childNodes();
            for(int i=0;i<nodeList.size();i++)
            {
                if(nodeList.at(i).toElement().tagName()=="FileRef"&&nodeList.at(i).toElement().attribute("persistAs").endsWith(".etp"))
                {
                    QString etpFileDir=QFileInfo(scadeProjectFilePath).absolutePath();
                    QString libFilePath=nodeList.at(i).toElement().attribute("persistAs").replace("\\","/");

                    QString libFileFullPath=etpFileDir+"/"+libFilePath;

                    if(QFileInfo(element.attribute("persistAs")).fileName()!=QFileInfo(scadeProjectFilePath).fileName())
                    {
                        projectInfo->projectLibsName.append(libFileFullPath);
                    }
                }
            }
        }

        //外部代码
        if(element.attribute("name")=="External Code")
        {
            QDomNodeList codeList=element.firstChild().childNodes();
            for(int j=0;j<codeList.count();j++)
            {
                QDomNode node=codeList.at(j);
                QDomElement ele=node.toElement();

                External_Code a;
                a.codeFileName=ele.attribute("persistAs");
                a.operatorName=ele.firstChild().childNodes().at(1).firstChild().toElement().text();

                projectInfo->externalCodes<<a;

                for(int k=0;k<projectInfo->opeartors.size();k++)
                {
                    if(projectInfo->opeartors.at(k).operatorName==a.operatorName)
                    {
                        projectInfo->opeartors[k].cFilePath=a.codeFileName;
                    }


                }
            }
        }

    }


    for(int i=0;i<otherModelFiles.count();i++)
    {

        QFile file(QFileInfo(SCADEProFile).absolutePath()+"/"+otherModelFiles.at(i));
        if(!file.open(QFile::ReadOnly))
            return;

        QDomDocument doc;

        if(!doc.setContent(&file))
        {
            file.close();
            return;
        }
        file.close();

        QDomElement root=doc.documentElement();
        TypeImport typeImporter;
        typeImporter.getTypeList_64(root);
        for(int k = 0; k < typeImporter.m_datas.size(); k++){
            projectInfo->typeList.append(typeImporter.m_datas.at(k));
        }
        projectInfo->logList.append(typeImporter.logList);
        //typeImporter.saveTypeList_64(defaultFile, projectInfo->typeList);
        //ConstantImport ConstantImporter;
        //ConstantImporter.constantImport_64(defaultFile,root);


        QDomNodeList nodeList=root.firstChild().childNodes();
        for(int n=0;n<nodeList.size();n++)
        {
            //顶层package
            if(nodeList.at(n).toElement().tagName()=="Package")
            {
                Package a;

                a.isSeparate=true;
                a.packageNode=root.firstChild().firstChild();
                a.packageName=a.packageNode.toElement().attribute("name");
                a.path=a.packageName+"_";
                a.packageFileName=otherModelFiles.at(i);

                QDomNodeList infoList=a.packageNode.firstChild().childNodes();
                for(int m=0;m<infoList.count();m++)
                {
                    QDomNode node=infoList.at(m);
                    QDomElement ele=node.toElement();

                    packageParse(QFileInfo(QFileInfo(scadeProjectFilePath).absolutePath()+"/"+a.packageFileName).absolutePath(),a,ele);

                }

                projectInfo->packages<<a;

            }

            //顶层操作符
            if(nodeList.at(n).toElement().tagName()=="Operator")
            {
                Operator a;

                a.isSeparate=true;
                a.operatorName=root.firstChild().firstChild().toElement().attribute("name");
                a.path=a.operatorName;
                a.operatorFileName=otherModelFiles.at(i);

                a.operatorNode=root.firstChild().firstChild();

                projectInfo->opeartors<<a;
            }
        }

    }
}

void ProjectInfoImport::proInfoProcess(QFile &file)//处理SCADE工程的工程信息转换成REDACE工程信息
{    
    if( !file.open(QIODevice::Append | QIODevice::Text) )
        return;

    QTextStream out(&file);

    if(!sProInfo.externalCodes.isEmpty())
    {
        out<<QString("外部代码:")<<endl;

        //外部代码信息处理
        for(int i=0;i<sProInfo.externalCodes.count();i++)
        {
            rProInfo.operatorCFilePath<<sProInfo.externalCodes.at(i).codeFileName;
            out<<QString("操作符：")+sProInfo.externalCodes.at(i).operatorName+QString("  代码：")+sProInfo.externalCodes.at(i).codeFileName<<endl;
        }

        out<<endl;

    }

    //默认模型文件处理
    if(!sProInfo.defaultFile.isEmpty())
    {
        rProInfo.commFilePath=sProInfo.defaultFile;
        rProInfo.commFilePath.replace(rProInfo.commFilePath.length()-6,6,"redace");
    }


    //        RProInfo.commFilePath=SProInfo.defaultFile.replace(SProInfo.defaultFile.length()-6,6,"redace");

    //操作符文件处理
    for(int i=0;i<sProInfo.opeartors.count();i++)
    {
        rProInfo.opeartors<<sProInfo.opeartors.at(i);
        rProInfo.opeartors[i].operatorName=rProInfo.opeartors.at(i).operatorName;

        rProInfo.opeartors[i].operatorFileName=rProInfo.opeartors.at(i).operatorName+".redace";

    }

    //算法库信息处理
    if(!sProInfo.libraries.isEmpty())
    {
        out<<QString("使用的算法库如下:")<<endl;

        for(int i=0;i<sProInfo.libraries.count();i++)
        {
            rProInfo.libPath<<sProInfo.libraries.at(i);
            out<<sProInfo.libraries.at(i)<<endl;
        }

        out<<endl;
    }

    file.close();

}

void ProjectInfoImport::generateSolutionFile(QString redaceProjectPath,QString scadeProjectName)//生成解决方案文件,redaceProjectPath为REDACE工程位置,scadeProjectName为工程名
{
    QString dirName=redaceProjectPath+"/"+scadeProjectName;//REDACE工程文件夹
    //    QDir dir(dirName);
    //    if(!dir.exists())
    //        dir.mkdir(dirName);//创建文件夹

    QString fileName=dirName+"/"+scadeProjectName+".rsf";
    QFile file(fileName);//创建解决方案文件
    QFileInfo fileInfo=QFileInfo(fileName);

    if(!file.open(QFile::WriteOnly|QFile::Truncate))
        return;

    //使用流方式写Xml文件。使用DOM写Xml时节点属性顺序会随机
    QXmlStreamWriter writer(&file);

    writer.setAutoFormatting(true);
    writer.setAutoFormattingIndent(2);

    //写入StartDocument
    writer.writeStartDocument();

    //写Solution节点
    writer.writeStartElement("Solution");
    writer.writeAttribute("GUID","");
    writer.writeAttribute("IsReadOnly","");
    writer.writeAttribute("DescripInfo","");
    writer.writeAttribute("Name",scadeProjectName);
    writer.writeAttribute("Path",".\\"+scadeProjectName+".rsf");

    //写Project节点
    writer.writeStartElement("Project");
    writer.writeAttribute("GUID",QUuid::createUuid().toString(QUuid::WithoutBraces));
    writer.writeAttribute("IsReadOnly","true");
    writer.writeAttribute("CRC","");//CRC值暂时为空
    writer.writeAttribute("Name",scadeProjectName);
    writer.writeAttribute("Path",".\\"+scadeProjectName+".rpf");
    writer.writeEndElement();
    writer.writeEndDocument();

    file.close();


    //    QDomDocument doc;

    //    //添加处理命令
    //    QDomProcessingInstruction instruction;
    //    instruction=doc.createProcessingInstruction("xml","version=\"1.0\" encoding=\"utf-8\"");
    //    doc.appendChild(instruction);

    //    //建立根节点Solution
    //    QDomElement root=doc.createElement("Solution");
    //    doc.appendChild(root);
    //    root.setAttribute("GUID",NULL);
    //    root.setAttribute("IsReadOnly",NULL);
    //    root.setAttribute("DescripInfo",NULL);
    //    root.setAttribute("Name",scadeProjectName);
    //    root.setAttribute("Path",".\\"+scadeProjectName+".rsf");

    //    //建立Solution的子节点Project
    //    QDomElement project=doc.createElement("Project");
    //    root.appendChild(project);
    //    project.setAttribute("GUID",QUuid::createUuid().toString(QUuid::WithoutBraces));
    //    project.setAttribute("IsReadOnly","true");
    //    project.setAttribute("CRC",NULL);//CRC值暂时为空
    //    project.setAttribute("Name",scadeProjectName);
    //    project.setAttribute("Path",".\\"+scadeProjectName+".rpf");

    //    //保存解决方案文件
    //    QTextStream out_stream(&file);
    //    doc.save(out_stream,4);
    //    file.close();

}

void ProjectInfoImport::generateProjectFile(QString redaceProjectPath,QString scadeProjectName)//生成工程文件,redaceProjectPath为REDACE工程位置，scadeProjectName为工程名
{
    QString fileName=redaceProjectPath+"/"+scadeProjectName+"/"+scadeProjectName+".rpf";
    QFile file(fileName);//创建工程文件
    QFileInfo fileInfo=QFileInfo(fileName);

    if(!file.open(QFile::WriteOnly|QFile::Truncate))
        return;

    //使用流方式写Xml文件。使用DOM写Xml时节点属性顺序会随机
    QXmlStreamWriter writer(&file);

    writer.setAutoFormatting(true);
    writer.setAutoFormattingIndent(2);

    //写入StartDocument
    writer.writeStartDocument();

    //写入Project节点
    writer.writeStartElement("Project");//开始Project节点
    writer.writeAttribute("id","");
    writer.writeAttribute("oid_count","");
    writer.writeAttribute("defaultConfiguration","");
    writer.writeAttribute("version","1.0.9");
    writer.writeAttribute("Name",scadeProjectName);
    writer.writeAttribute("Path",".\\"+scadeProjectName+".rpf");

    //写roots节点
    writer.writeStartElement("roots");//开始roots节点

    //写外部代码
    writer.writeStartElement("Folder");//开始外部代码文件的Folder节点
    writer.writeAttribute("id","0");
    writer.writeAttribute("extensions","redace");
    writer.writeAttribute("foldertype","operatorcfile");
    writer.writeAttribute("Name","operatorcfile");
    writer.writeAttribute("Path","");

    //    for(int i=0;i<rProInfo.operatorCFilePath.count();i++)
    //    {
    //        writer.writeStartElement("FileRef");//开始外部代码文件的FileRef节点
    //        writer.writeAttribute("id","0");
    //        writer.writeAttribute("CRC","");
    //        writer.writeAttribute("Name",rProInfo.operatorCFilePath.at(i));
    //        writer.writeAttribute("Path",".\\"+rProInfo.operatorCFilePath.at(i));
    //        writer.writeEndElement();//结束外部代码文件的FileRef节点
    //    }

    writer.writeEndElement();//结束外部代码文件的Folder节点

    //写默认模型文件。（无论SCADE工程是否存在默认模型文件，REDACE工程必定存在默认模型文件）
    writer.writeStartElement("Folder");//开始默认模型文件的Folder节点
    writer.writeAttribute("id","0");
    writer.writeAttribute("extensions","redace");
    writer.writeAttribute("foldertype","comm");
    writer.writeAttribute("Name","comm");
    writer.writeAttribute("Path","");

    writer.writeStartElement("FileRef");//开始默认模型文件的FileRef节点
    writer.writeAttribute("id","0");
    writer.writeAttribute("CRC","");
    writer.writeAttribute("Name",scadeProjectName);
    writer.writeAttribute("Path",".\\"+scadeProjectName+".redace");
    writer.writeEndElement();//结束默认模型文件的FileRef节点

    writer.writeEndElement();//结束默认模型文件的Folder节点

    //写操作符文件。
    writer.writeStartElement("Folder");//开始默认模型文件的Folder节点
    writer.writeAttribute("id","0");
    writer.writeAttribute("extensions","redace");
    writer.writeAttribute("foldertype","operator");
    writer.writeAttribute("Name","operators");
    writer.writeAttribute("Path","");

    for(int i=0;i<rProInfo.opeartors.count();i++)
    {
        writer.writeStartElement("FileRef");//开始操作符文件的FileRef节点
        writer.writeAttribute("id","0");
        writer.writeAttribute("CRC","");
        writer.writeAttribute("Name",rProInfo.opeartors.at(i).operatorName);
        writer.writeAttribute("Path",".\\"+rProInfo.opeartors.at(i).operatorFileName);

        writer.writeEndElement();//结束操作符文件的FileRef节点
    }

    writer.writeEndElement();//结束操作符文件的Folder节点

    //写普通算法库
    writer.writeStartElement("Folder");//开始普通算法库的Folder节点
    writer.writeAttribute("id","0");
    writer.writeAttribute("extensions","rlf");
    writer.writeAttribute("foldertype","nomalLib");
    writer.writeAttribute("Name","NomalLib");
    writer.writeAttribute("Path","");

    writer.writeEndElement();//结束普通算法库的Folder节点

    //写加密算法库
    writer.writeStartElement("Folder");//开始加密算法库的Folder节点
    writer.writeAttribute("id","0");
    writer.writeAttribute("extensions","rlf");
    writer.writeAttribute("foldertype","encryptedLib");
    writer.writeAttribute("Name","EncryptionLib");
    writer.writeAttribute("Path","");

    writer.writeEndElement();//结束加密算法库的Folder节点

    //写package
    writer.writeStartElement("Folder");//开始package的Folder节点
    writer.writeAttribute("id","0");
    writer.writeAttribute("extensions","redace");
    writer.writeAttribute("foldertype","package");
    writer.writeAttribute("Name","package");
    writer.writeAttribute("Path","");

    writer.writeEndElement();//结束package的Folder节点

    writer.writeEndElement();//结束roots节点

    //写information节点
    writer.writeStartElement("information");//开始information节点
    writer.writeAttribute("slnName",scadeProjectName);
    writer.writeEndElement();//结束information节点

    writer.writeEndElement();//结束Project节点
    writer.writeEndDocument();

    file.close();

}
